package com.mainbo.modular.excel.impl;

import cn.hutool.core.io.resource.ClassPathResource;
import cn.stylefeng.roses.core.util.HttpContext;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.mainbo.core.common.constant.Const;
import com.mainbo.core.shiro.SessionKey;
import com.mainbo.core.shiro.ShiroKit;
import com.mainbo.core.util.AccountGenerator;
import com.mainbo.core.util.EncryptPassword;
import com.mainbo.core.util.ExcelUtils;
import com.mainbo.modular.excel.BatchImportService;
import com.mainbo.modular.excel.ExcelBatchService;
import com.mainbo.modular.jms.JmsService;
import com.mainbo.modular.jms.MessageTypes;
import com.mainbo.modular.system.dao.PtAccountMapper;
import com.mainbo.modular.system.model.*;
import com.mainbo.modular.system.model.excelUser.EduEmployee;
import com.mainbo.modular.system.model.People;
import com.mainbo.modular.system.model.Student;
import com.mainbo.modular.system.model.Teacher;
import com.mainbo.modular.system.model.meta.GBNation;
import com.mainbo.modular.system.model.meta.GBPapersType;
import com.mainbo.modular.system.model.meta.GBSex;
import com.mainbo.modular.system.model.meta.MetaUtils;
import com.mainbo.modular.system.model.meta.vo.Meta;
import com.mainbo.modular.system.service.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.poi.ss.usermodel.DataValidation;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.*;

/**
 * @Author xww
 * @Description //TODO
 * @Date 2020/2/26   9:18
 **/
@Service
public class BatchImportServiceImpl extends ExcelBatchService implements BatchImportService {
    private static final  Logger logger= LoggerFactory.getLogger(BatchImportServiceImpl.class);
    private static final String USERTYPE = "userType";

    private static final String ORG_ID = "orgId";
    @Autowired
    private IPtOrgService orgService;
    @Autowired
    private IPtAreaService areaService;
    @Autowired
    private IPtRoleService roleService;
    @Autowired
    private IPtUserRoleService userRoleService;
    @Autowired
    private EduEmpService eduEmpService;
    @Autowired
    private StudentService studentService;
    @Autowired
    private TeacherService teacherService;
    @Autowired
    private PeopleService peopleService;
    @Resource
    private AccountGenerator accountGenerator;
    @Resource
    private PtAccountMapper accountMapper;
    @Resource
    private JmsService jmsService;
    @Override
    public void getRegisterTemplate(Integer templateType, Integer phaseId, String orgId, HttpServletResponse response) throws IOException {
        Workbook workbook = null;
        String filepath = null;
        String fileName = "";
        switch (templateType) {
            case PtAccount.AREA_USER:
                fileName = "区域用户信息表";
                break;
            case PtAccount.TEACHER_USER:
                fileName = "教职工用户信息表";
                break;
            case PtAccount.STUDENT_USER:
                fileName = "学生用户信息表";
                break;
            case PtAccount.PARENTS_USER:
                fileName = "家长用户信息表";
                break;
            default:
                fileName = "系统用户信息表";
                break;
        }
        PtOrg orgName = orgService.selectById(orgId);
        if (orgName != null) {
            String areaName = orgService.getAreaNameById(orgName.getAreaId());
            fileName = areaName + orgName.getShortName() + fileName;
        }
        Map<String, Object> params = new HashMap<String, Object>();
        if (PtAccount.AREA_USER == templateType) { // 教育局用户模板
            filepath = "/registertemplate/registertemplate_qyyh.xls";
            ClassPathResource resource = new ClassPathResource(filepath);
            InputStream inputStream = resource.getStream();
            workbook = ExcelUtils.createWorkBook(inputStream, ExcelUtils.ExcelType.EXL_2003);
            if (workbook == null) {
                returnErrMsg(filepath, response);
                return;
            }
            Sheet sheet = workbook.getSheet("Sheet1");
            PtOrg org = orgService.selectById(orgId);
            String orgStr = "单位名称：" + org.getName();
            PtArea area1 = areaService.selectById(org.getAreaId());
            if (0 != area1.getPid()) {
                PtArea area2 = areaService.selectById(area1.getPid());
                orgStr = "省(市)：" + area2.getAreaName() + "     区(县)：" + area1.getAreaName() + "   " + orgStr;
            } else {
                orgStr = "区(县)：" + area1.getAreaName() + orgStr;
            }
            sheet.getRow(2).getCell(0).setCellValue(orgStr);
            Map<ExcelTitle, Column> headers = parseExcelHeader(sheet, params);
            initAreaSheetTeplate(sheet, org, phaseId, headers);
        } else if (PtAccount.TEACHER_USER == templateType) { // 教师用户模板
            filepath = "/registertemplate/registertemplate_xxyh.xls";
            ClassPathResource resource = new ClassPathResource(filepath);
            InputStream inputStream = resource.getStream();
            workbook = ExcelUtils.createWorkBook(inputStream, ExcelUtils.ExcelType.EXL_2003);
            if (workbook == null) {
                returnErrMsg(filepath, response);
                return;
            }
            Sheet sheet = workbook.getSheet("Sheet1");
            PtOrg org = orgService.selectById(orgId);
            PtArea area1 = areaService.selectById(org.getAreaId());
            String orgStr = "学校名称：" + org.getName();
            if (0 != area1.getPid()) {
                PtArea area2 = areaService.selectById(area1.getPid());
                orgStr = "省(市)：" + area2.getAreaName() + "     区(县)：" + area1.getAreaName() + "   " + orgStr;
            } else {
                orgStr = "区(县)：" + area1.getAreaName() + "   " + orgStr;
            }
            sheet.getRow(2).getCell(0).setCellValue(orgStr);
            Map<ExcelTitle, Column> headers = parseExcelHeader(sheet, params);
            initSheetTeplate(templateType, workbook, sheet, org, phaseId, headers);
        } else if (PtAccount.STUDENT_USER == templateType || PtAccount.PARENTS_USER == templateType) { // 学生用户模板
            if (PtAccount.PARENTS_USER == templateType) {
                filepath = "/registertemplate/registertemplate_jzyh.xls";
            } else {
                filepath = "/registertemplate/registertemplate_xsyh.xls";
            }
            ClassPathResource resource = new ClassPathResource(filepath);
            InputStream inputStream = resource.getStream();
            workbook = ExcelUtils.createWorkBook(inputStream, ExcelUtils.ExcelType.EXL_2003);
            if (workbook == null) {
                returnErrMsg(filepath, response);
                return;
            }
            Sheet sheet = workbook.getSheet("Sheet1");
            PtOrg org = orgService.selectById(orgId);
            PtArea area1 = areaService.selectById(org.getAreaId());
            String orgStr = "";
            if (0 != area1.getPid()) {
                PtArea area2 = areaService.selectById(area1.getPid());
                orgStr = "省(市)：" + area2.getAreaName() + "     区(县)：" + area1.getAreaName();
            } else {
                orgStr = "区(县)：" + area1.getAreaName();
            }
            sheet.getRow(2).getCell(0).setCellValue(orgStr);
            Map<ExcelTitle, Column> headers = parseExcelHeader(sheet, params);
            initSheetTeplate(templateType, workbook, sheet, org, phaseId, headers);
        }

        try {
            response.reset();
            response.setContentType("application/x-msdownload");
            response.setHeader("Content-Disposition",
                    "attachment; filename=" + new String(fileName.getBytes("gb2312"), "ISO-8859-1") + ".xls");
            if (workbook != null) {
                workbook.write(response.getOutputStream());
            }
        } catch (Exception e) {
            logger.error("", e);
        } finally {
            if (workbook != null) {
                try {
                    workbook.close();
                } catch (IOException e) {
                    logger.error("close failed", e);
                }
            }
        }
    }

    @Override
    public StringBuilder batchRegiterUser(Integer userType, String orgId, Integer phaseId, MultipartFile file) {
        Map<String, Object> params = new HashMap<String, Object>();
        StringBuilder resultStr = new StringBuilder(); // 反馈信息
        params.put(ORG_ID, orgId);
        params.put("phaseId", phaseId);
        params.put(USERTYPE, userType);
        params.put("batchUserList", new ArrayList<CommUser>());// 待插入用户集合
        params.put("batchUpdateUserList", new HashSet<CommUser>());// 待更新用户角色集合

        long start = System.currentTimeMillis();
        boolean failed = false;
        try {
            resultStr.append("<strong>==》开始导入数据</strong><br>");
            super.importData(file.getInputStream(), ExcelUtils.ExcelType.parseExcelType(file.getOriginalFilename()), params, resultStr,userType,orgId);
            resultStr.append("<br><strong>《==数据导入结束。</strong>");
        } catch (Exception e) {
            logger.error("read excel file failed", e);
            resultStr.append("批量导入失败：").append(e.getMessage());
            failed = true;
        }

        if (!failed) {
            long end = System.currentTimeMillis();
            HashMap<String, Object> paras = new HashMap<String, Object>();

            paras.put("begin_time", start);
            paras.put("end_time", end);
            switch (userType) {
                case 2:
                    userType = SysRole.AREAWORKER.getId();
                    break;
                case 3:
                    userType = SysRole.TEACHER.getId();
                    break;
                case 4:
                    userType = SysRole.STUDENT.getId();
                    break;
                default:
                    userType = SysRole.PARRENT.getId();
                    break;
            }

            paras.put(ORG_ID, orgId);
            List<CommUser> userInfos = (List<CommUser>) params.get("batchUserList"); // 发送消息
            if (userInfos.size() > 0) {
                if (SysRole.TEACHER.getId().equals(userType)){
                    paras.put(USERTYPE, SysRole.TEACHER.getId());
                    jmsService.sendMessage(MessageTypes.USER_BATCH_ADD.name(), paras);
                    paras.put(USERTYPE, SysRole.SCHMANAGER.getId());
                    jmsService.sendMessage(MessageTypes.USER_BATCH_ADD.name(), paras);
                    paras.put(USERTYPE, SysRole.SCHWORKER.getId());
                    jmsService.sendMessage(MessageTypes.USER_BATCH_ADD.name(), paras);
                }else {
                    paras.put(USERTYPE, userType);
                    jmsService.sendMessage(MessageTypes.USER_BATCH_ADD.name(), paras);
                }

            }
            Set<CommUser> batchUpdateUserList = (HashSet<CommUser>) params.get("batchUpdateUserList");
            if (batchUpdateUserList.size() > 0 || SysRole.PARRENT.getId().equals(userType)) {
                if (SysRole.TEACHER.getId().equals(userType)){
                    paras.put(USERTYPE, SysRole.TEACHER.getId());
                    jmsService.sendMessage(MessageTypes.USER_BATCH_UPDATE.name(), paras);
                    paras.put(USERTYPE, SysRole.SCHMANAGER.getId());
                    jmsService.sendMessage(MessageTypes.USER_BATCH_UPDATE.name(), paras);
                    paras.put(USERTYPE, SysRole.SCHWORKER.getId());
                    jmsService.sendMessage(MessageTypes.USER_BATCH_UPDATE.name(), paras);
                }else {
                    paras.put(USERTYPE, userType);
                    jmsService.sendMessage(MessageTypes.USER_BATCH_UPDATE.name(), paras);
                }
            }
        }

        return resultStr;
    }

    /**
     * 初始化区域用户模板
     *
     * @param sheet   工作簿对象
     * @param org     机构
     * @param phaseId 学段
     */
    private void initAreaSheetTeplate(Sheet sheet, PtOrg org, Integer phaseId, Map<ExcelTitle, Column> headers) {
        PtAccount current=ShiroKit.getSessionAttr(SessionKey.CURRENT_USER);
        Column cn = null;
        if ((cn = headers.get(ExcelHeader.SEX)) != null) {
            int clumnIndex = cn.getIndex();
            String sexStr = "";
            for (GBSex sex : GBSex.values()) {
                sexStr = sexStr + "," + sex.getCname();
            }
            String[] sexStrings = sexStr.split(",");
            sheet = setPromptOfCell(sheet, sexStrings, titleLine() + 1, 2000, clumnIndex, clumnIndex);
        }

        if ((cn = headers.get(ExcelHeader.ROLETYPE)) != null) {
            int clumnIndex = cn.getIndex();
            List<SysRole> roleList = new ArrayList<SysRole>();
            for (SysRole role : SysRole.values()) {
                if (role.getScope() == 1) {
                    roleList.add(role);
                }
            }

            sheet = setPromptOfCell(sheet, objectListToStringArray(roleList, "getCname", false), titleLine() + 1, 2000,
                    clumnIndex, clumnIndex); //
        }

        if ((cn = headers.get(ExcelHeader.ROLE)) != null) {
            int clumnIndex = cn.getIndex();
            String orgId =current.getOrgId();
            if (StringUtils.isEmpty(orgId)) {
                orgId = Const.DEFAULT_ORG_ID;
            }
            List<PtRole> roleList = roleService.getRoleByScope(org.getId(), PtRoleType.APPLICATION_AREA);
            sheet = setPromptOfCell(sheet, objectListToStringArray(roleList, "getRoleName", false), titleLine() + 1, 2000,
                    clumnIndex, clumnIndex); //
        }
        if ((cn = headers.get(ExcelHeader.ROLE)) != null) {
            int clumnIndex = cn.getIndex();
            String orgId =current.getOrgId();
            if (StringUtils.isEmpty(orgId)) {
                orgId = Const.DEFAULT_ORG_ID;
            }
            List<PtRole> roleList = roleService.getRoleByScope(org.getId(), PtRoleType.APPLICATION_AREA);
            sheet = setPromptOfCell(sheet, objectListToStringArray(roleList, "getRoleName", false), titleLine() + 1, 2000,
                    clumnIndex, clumnIndex); //
        }

        if ((cn = headers.get(ExcelHeader.PHASE)) != null) {
            int clumnIndex = cn.getIndex();
            List<Meta> xueduanMeataList = MetaUtils.getPhaseProvider().listAll();
            sheet = setPromptOfCell(sheet, objectListToStringArray(xueduanMeataList, "getName", false), titleLine() + 1, 2000,
                    clumnIndex, clumnIndex); //
        }

        if ((cn = headers.get(ExcelHeader.SUBJECT)) != null) {
            Integer[] areaIds = this.getAreaIds(org);
            List<Meta> subjectNameSet = new ArrayList<Meta>();
            if (PtOrg.TP_SCHOOL == org.getType()) {
                subjectNameSet = MetaUtils.getPhaseSubjectProvider().listAllSubject(org.getId(), phaseId, areaIds);
            } else if (PtOrg.TP_ORG == org.getType()) {
                subjectNameSet = MetaUtils.getPhaseSubjectProvider().listAllSubject(null, phaseId, areaIds);
            }
            String[] subjectArray = objectListToStringArray(subjectNameSet, "getName", false);
            String[] subs = new String[subjectArray.length + 1];
            System.arraycopy(subjectArray, 0, subs, 0, subjectArray.length);
            subs[subjectNameSet.size()] = "无";
            int clumnIndex = cn.getIndex();
            sheet = setPromptOfCell(sheet, subs, titleLine() + 1, 2000, clumnIndex, clumnIndex); // 学科
        }
    }
    private void initSheetTeplate(Integer temlateType, Workbook workbook, Sheet sheet, PtOrg org, Integer phaseId,
                                  Map<ExcelTitle, Column> headers) {
        PtAccount current=ShiroKit.getSessionAttr(SessionKey.CURRENT_USER);
        Column cn = null;
        Integer subjectColumnIndex = null;
        Integer gradeColumnIndex = null;
        if ((cn = headers.get(ExcelHeader.SEX)) != null) {
            int clumnIndex = cn.getIndex();
            String sexStr = "";
            for (GBSex sex : GBSex.values()) {
                sexStr = sexStr + "," + sex.getCname();
            }
            String[] sexStrings = sexStr.split(",");
            sheet = setPromptOfCell(sheet, sexStrings, titleLine() + 1, 2000, clumnIndex, clumnIndex);
        }

        if ((cn = headers.get(ExcelHeader.ROLETYPE)) != null) {
            int clumnIndex = cn.getIndex();
            List<SysRole> roleList = new ArrayList<SysRole>();
            for (SysRole role : SysRole.values()) {
                if (role.getScope() == 2) {
                    roleList.add(role);
                }
            }

            sheet = setPromptOfCell(sheet, objectListToStringArray(roleList, "getCname", false), titleLine() + 1, 2000,
                    clumnIndex, clumnIndex); //
        }
        if ((cn = headers.get(ExcelHeader.ROLE)) != null) {
            int clumnIndex = cn.getIndex();
            String orgId =current.getOrgId();
            if (StringUtils.isEmpty(orgId)) {
                orgId = Const.DEFAULT_ORG_ID;
            }
            List<PtRole> roleList = roleService.getRoleByScope(org.getId(), PtRoleType.APPLICATION_SCHOOL);
            sheet = setPromptOfCell(sheet, objectListToStringArray(roleList, "getRoleName", false), titleLine() + 1, 2000,
                    clumnIndex, clumnIndex); // 职务
        }

        if ((cn = headers.get(ExcelHeader.SUBJECT)) != null) {
            subjectColumnIndex = cn.getIndex();
            Integer[] areaIds = this.getAreaIds(org);
            List<Meta> subjectNameSet = MetaUtils.getPhaseSubjectProvider().listAllSubject(org.getId(), phaseId, areaIds);
            String[] subjectArray = objectListToStringArray(subjectNameSet, "getName", false);
            String[] subs = new String[subjectArray.length + 1];
            System.arraycopy(subjectArray, 0, subs, 0, subjectArray.length);
            subs[subjectNameSet.size()] = "无";
            sheet = setPromptOfCell(sheet, subs, titleLine() + 1, 2000, subjectColumnIndex, subjectColumnIndex); // 学科
        }

        if ((cn = headers.get(ExcelHeader.GRADE)) != null) {
            gradeColumnIndex = cn.getIndex();
            List<Meta> gradeMetas = MetaUtils.getOrgTypeProvider().listAllGrade(org.getSchoolings(), phaseId);
            String[] gradenames = new String[gradeMetas.size() + 1];
            int i = 0;
            for (Meta sc : gradeMetas) {
                gradenames[i++] = sc.getName();
            }
            gradenames[i] = "无";
            sheet = setPromptOfCell(sheet, gradenames, titleLine() + 1, 2000, gradeColumnIndex, gradeColumnIndex); // 年级
        }
        if ((cn = headers.get(ExcelHeader.PHASE)) != null) {
            int clumnIndex = cn.getIndex();
            List<Meta> phaseMate = MetaUtils.getPhaseProvider().listAllPhase();
            String[] phasenames = new String[phaseMate.size() + 1];
            int i = 0;
            for (Meta sc : phaseMate) {
                phasenames[i++] = sc.getName();
            }
            phasenames[i] = "无";
            sheet = setPromptOfCell(sheet, phasenames, titleLine() + 1, 2000, clumnIndex, clumnIndex); // 学段
        }
    }
    private void returnErrMsg(String path, HttpServletResponse response) {
        response.setHeader("Content-type", "text/html;charset=UTF-8");
        StringBuilder rb = new StringBuilder(path).append(" 不存在!");
        try {
            response.getWriter().write(rb.toString());
        } catch (IOException e) {
            logger.error("", e);
        }
    }
    /**
     * 设置单元格的下拉框
     *
     * @param sheet    工作簿对象
     * @param textList 文本集合
     * @param firstRow 第一排
     * @param endRow  最后一排
     * @param firstCol 第一行
     * @param endCol  最后一行
     * @return 返回
     */
    private Sheet setPromptOfCell(Sheet sheet, String[] textList, int firstRow, int endRow, int firstCol, int endCol) {
        // 加载下拉列表内容
        DataValidation dataValidationList = ExcelUtils.createDataValidation(sheet, textList, firstRow, endRow, firstCol,
                endCol);
        sheet.addValidationData(dataValidationList);
        return sheet;
    }
    @Override
    protected String prepareTitle(String name) {
        name = super.prepareTitle(name);
        return name != null && name.length() > 4 ? name.replaceAll("\\(必填\\)", "") : name;
    }
    /**
     * 从对象的集合获取某个字段的数组
     *
     * @param objectList 对象集合
     * @param paramName  参数名
     * @return 返回
     * @throws Exception 异常
     */
    private <T> String[] objectListToStringArray(List<T> objectList, String paramName, boolean allowNull) {
        List<String> textList = new ArrayList<String>();
        Method m = null;
        try {
            for (int i = 0; i < objectList.size(); i++) {
                m = objectList.get(i).getClass().getDeclaredMethod(paramName);
                String value = (String) m.invoke(objectList.get(i));
                if (StringUtils.isNotEmpty(value)) {
                    textList.add(value);
                }
            }
        } catch (Exception e) {
            logger.error("invoke {} failed", paramName);
            logger.error("", e);
        }
        if (allowNull) {
            textList.add("无");
        }
        return textList.toArray(new String[textList.size()]);
    }
    private SysRole parseUserRoleType(Integer userType, Map<String, SysRole> userRoleTypeMap, String name,
                                      String roleTypeName) {
        SysRole role = null;
        switch (userType) {
            case PtAccount.AREA_USER:
            case PtAccount.TEACHER_USER:
                role = userRoleTypeMap.get(name);
                if (role == null) {
                    role = SysRole.findByCname(roleTypeName);
                }
                break;
            case PtAccount.STUDENT_USER:
                role = SysRole.STUDENT;
                break;
            case PtAccount.PARENTS_USER:
                role = SysRole.PARRENT;
                break;
            case PtAccount.SYSTEM_USER:
                role = SysRole.ADMIN;
                break;
            default:
                role = SysRole.UNKNOWN;
        }
        return role;
    }
    // 获得区域ids
    private Integer[] getAreaIds(PtOrg o) {
        List<Integer> areaIds = new ArrayList<Integer>();
        if (o != null && o.getAreaIds() != null) {
            String[] areaId = o.getAreaIds().split(",");
            for (int i = 0; i < areaId.length; i++) {
                if (!StringUtils.isEmpty(areaId[i])) {
                    areaIds.add(Integer.valueOf(areaId[i]));
                }
            }
        }
        return areaIds.toArray(new Integer[areaIds.size()]);
    }

    @Override
    protected ExcelTitle[] titles() {
        return  ExcelHeader.values();
    }

    @Override
    public int sheetIndex() {
        return 0;
    }

    @Override
    public int titleLine() {
        return 3;
    }

    @Override
    protected void parseRow(Map<ExcelTitle, String> rowValueMap, Map<String, Object> params, Row row, StringBuilder returnMsg) {
        Integer userType = (Integer) params.get(USERTYPE);
        String orgId = (String) params.get(ORG_ID);
        Map<String, PtUserRole> areadySpaceIdMap = (Map<String, PtUserRole>) params.get("areadySpaceIdMap");// 已经存在的用户空间id
        Map<String, String> userRoleTempMap = (Map<String, String>) params.get("spaceTempMap"); // 临时空间map
        Map<String, CommUser> userTempMap = (Map<String, CommUser>) params.get("userTempMap"); // 记录最新用户信息
        Map<String, SysRole> userRoleTypeMap = (Map<String, SysRole>) params.get("userRoleTypeMap");
        List<PtUserRole> batchSpaceList = (ArrayList<PtUserRole>) params.get("batchSpaceList");// 待插入用户角色集合

        Set<CommUser> batchUpdateUserList = (HashSet<CommUser>) params.get("batchUpdateUserList");// 待更新用户角色集合
        List<CommUser> batchUserList = (ArrayList<CommUser>) params.get("batchUserList");// 待插入用户集合
        List<CommUser> batchDeleteUserList = (ArrayList<CommUser>) params.get("batchDeleteUserList");// 待删除用户集合

        Map<String, PtRole> roleMap = (Map<String, PtRole>) params.get("roleMap");// 临时用户map<用户姓名，用户object>,用于判断待插入的数据是否重复

        PtOrg org = orgService.selectById(orgId);

        int i = row.getRowNum() + 1;
        CommUser userInfo = fillCommUserInfo(userType, rowValueMap);// 填充用户信息，根据用户类型选择实际用户表
        userInfo.setOrgId(orgId);
        userInfo.setOrgName(org.getName());

        String role = rowValueMap.get(ExcelHeader.ROLE);
        String subject = rowValueMap.get(ExcelHeader.SUBJECT);
        String phase = rowValueMap.get(ExcelHeader.PHASE);
        String grade = rowValueMap.get(ExcelHeader.GRADE);
        String roleTypeName = rowValueMap.get(ExcelHeader.ROLETYPE);
        PtRole role2 = roleMap.get(role);

        SysRole roleType = parseUserRoleType(userType, userRoleTypeMap, userInfo.getName(), roleTypeName);
        if (roleType == SysRole.UNKNOWN) {
            returnMsg.append("数据错误：第" + (i) + "行数据角色类型不存在，已自动忽略;<br>");
        }

        // 新增用户空间（加入到待插入空间集合中）
        PtUserRole userSpace;
        if (role2 != null) {
            userSpace = newUserRole(i, userInfo.getName(), orgId, phase, grade, subject, role2, params, returnMsg,
                    roleType.getId());
        } else {
            userSpace = null;
        }

        CommUser teacher = userInfo;
        teacher.setFlago(String.valueOf(i));// 记录当前行
        String accountName = rowValueMap.get(ExcelHeader.ID);
        if (StringUtils.isNotBlank(accountName)) {
            parseExitsCount(userType, accountName, teacher, userTempMap, userRoleTempMap, areadySpaceIdMap);
        }

        String userKey = getUserKey(userType, userInfo);

        if (userTempMap.get(userKey) != null) { // 用户相同，存在更新
            teacher = userTempMap.get(userKey);//
            PtAccount account = accountService.selectById(teacher.getId());
            if (roleType == SysRole.UNKNOWN && userSpace != null) {
                userSpace.setSysRoleId(account.getUserType()); //
            }
            //compareAndRecord(userInfo, teacher, batchUpdateUserList);// 比较新旧用户信息
        } else { // 用户与之前不同
            if (roleType == SysRole.UNKNOWN) {
                return;
            }
            CommUser tempUser = findOldUser(userType, userInfo.getName(), userInfo.getCellphone(), orgId);

            if (tempUser == null) { // 数据库中用户不存在
                // 新增登陆信息
                PtAccount account = createLogin(i, org, roleType.getId(), userInfo.getCellphone(), userInfo.getName(),
                        accountName, false, returnMsg);
                // 新增用户信息（加入到待插入用户集合中）
                teacher.setId(account.getId());
                batchUserList.add(teacher);
            } else { // 用户已存在，增加身份
                PtAccount account = accountMapper.selectById(tempUser.getId());// 如账号不存在，说明是垃圾数据，重新创建，并清除垃圾数据
                if (account == null) {
                    account = createLogin(i, org, roleType.getId(), userInfo.getCellphone(), userInfo.getName(), accountName,
                            false, returnMsg);
                    teacher.setId(account.getId());
                    batchUserList.add(teacher);
                    batchDeleteUserList.add(tempUser);// 记录要删除的垃圾用户数据
                } else {
                   // compareAndRecord(userInfo, tempUser, batchUpdateUserList);// 比较新旧用户信息
                    if (userTempMap.get(userKey) == null) {
                        // 记录之前的身份
                        fillSpace(tempUser.getId(), tempUser.getOrgId(), userRoleTempMap, areadySpaceIdMap);
                    }

                    teacher = tempUser;
                }
            }

            userTempMap.put(userKey, teacher);
        }

        // 发布用户信息初始化事件， 监听器可处理改事件。
        Map<String, Object> eventData = new HashMap<String, Object>();
        eventData.put(USERTYPE, userType);
        eventData.put("rowValueMap", rowValueMap);
        eventData.put("userInfo", teacher);
        Date beforeInsertTime = (Date) params.get("beforeInsertTime"); // 开始插入时间
        eventData.put("beforeInsertTime", beforeInsertTime);// 开始插入时间
        eventData.put("returnMsg", returnMsg);// 提示信息对象
        eventData.put("rowNum", i);// 行数
       // fireListenableEvent(EVENT_BATCH_USER_INIT, eventData);

        if (userSpace != null) { // 处理用户空间
            String spkey = getUserKey(teacher.getId(), userSpace);
            if (userRoleTempMap.get(spkey) != null) { // 空间重复
                if (areadySpaceIdMap.get(spkey) != null) { // 去掉不要删除的职务
                    areadySpaceIdMap.remove(spkey);
                }
            } else {
                // 新增用户空间（加入到待插入空间集合中）
                userSpace.setAccountId(teacher.getId());
                batchSpaceList.add(userSpace);
                userRoleTempMap.put(spkey, "");
            }
        }

    }
    /**
     * 生成用户名时，全局认证
     *
     * @param org      机构
     * @param userName 用户名
     * @param isAdmin  是否默认
     * @return 返回
     */
    private PtAccount createLogin(int i, PtOrg org, Integer roleType, String cellPhone, String userName,
                                String accountName, boolean isAdmin, StringBuilder msg) {
        PtAccount account = new PtAccount();
        account.setUserType(roleType);

        // account.setDeleted(false);
        boolean foreAccount = false;
        if (foreAccount || StringUtils.isBlank(accountName) || !accountName.matches(PtAccount.USERNAME_PATTERN)) { // 生成用户名,用户输入为空，或强制使用生成用户名
            accountName = accountGenerator.validate(account);
        }
        account.setOrgId(org.getId());
        account.setAccount(accountName);
        int index = 0;
        PtAccount oldLogins = accountMapper.selectOne(account);
        String name = account.getAccount();
        while (oldLogins != null) { // 使用基数递增方式生成
            index++;
            account.setAccount(name + index);
            oldLogins = accountMapper.selectOne(account);
            if (index > 5) {
                index += 10;
            }
        }

        if ( cellPhone != null) {
            if (cellPhone.matches(PtAccount.MOBILE_PHONE_NUMBER_PATTERN)) { // 验证手机
                PtAccount model = new PtAccount();// 禁用不可恢复
                model.setDeleted(false);
                model.setCellphone(cellPhone);
                model = accountMapper.selectOne(model);
                if (model == null) {
                    account.setCellphone(cellPhone);
                } else {
                    msg.append("第").append(i).append("行，手机已被占用，可在个人中心绑定找回.<br/>");
                }
            } else {
                msg.append("第").append(i).append("行，手机格式错误，将不能使用手机号登录<br/>");
            }

        }

        String salt = "";
        String password = EncryptPassword.encryptPassword(Const.DEFAULT_PWD);
        account.setSalt(salt);
        account.setPassword(password);
        account.setEnable(true);
        account.setDeleted(false);
        accountService.insert(account);
        return account;
    }
    private String getUserKey(Integer userType, CommUser userInfo) {
        return userType != null && PtAccount.PARENTS_USER == userType ? userInfo.getCellphone() : userInfo.getName();
    }

    /**
     * 根据真实姓名查找用户
     *
     * @param userType 用户类型
     * @param userType     真实姓名
     * @param id    机构id
     * @return result
     */
    private CommUser findOldUser(Integer userType, String id) {
        CommUser user = null;
        switch (userType) {
            case PtAccount.AREA_USER:
                user = eduEmpService.selectById(id);
                break;
            case PtAccount.TEACHER_USER:
                user = teacherService.selectById(id);
                break;
            case PtAccount.STUDENT_USER:
                user = studentService.selectById(id);
                break;
            default:
                user = peopleService.selectById(id);
        }

        return user;
    }
    /**
     * 根据真实姓名查找用户
     *
     * @param userType 用户类型
     * @param name     姓名
     * @param orgId    机构id
     * @return 返回
     */
    private CommUser findOldUser(Integer userType, String name, String cellphone, String orgId) {
        CommUser model = createUser(userType);
        model.setName(name);
        model.setOrgId(orgId);
        CommUser user = null;
        switch (userType) {
            case PtAccount.AREA_USER:
                user = eduEmpService.getOne(name,orgId);
                break;
            case PtAccount.TEACHER_USER:
                user = teacherService.getOne(name,orgId);
                break;
            case PtAccount.STUDENT_USER:
                user = studentService.getOne(name,orgId);
                break;
            case PtAccount.PARENTS_USER:
                model.setOrgId(null);
                model.setName(null);
                model.setCellphone(cellphone);
                user = peopleService.getOne(orgId,name,cellphone);
                break;
            default:
                user = peopleService.getOne(orgId,name,cellphone);
        }

        return user;
    }

    private void parseExitsCount(Integer userType, String accountName, CommUser teacher,
                                 Map<String, CommUser> userTempMap, Map<String, String> userRoleTempMap, Map<String, PtUserRole> areadySpaceIdMap) {

        PtAccount account = accountService.getByAccountName(accountName);
        String userKey = getUserKey(userType, teacher);
        // 账号存在并且没有处理过
        if (account != null && userTempMap.get(userKey) == null) {
            CommUser old = findOldUser(userType, account.getId());
            if (old != null) { // 改账号关联用户存在
                userTempMap.put(userKey, old);
                fillSpace(old.getId(), old.getOrgId(), userRoleTempMap, areadySpaceIdMap);
            } else {
                logger.warn("账号[id:{},account:{}],用户信息不存在！", account.getId(), account.getAccount());
            }
        }
    }
    private void fillSpace(String id, String orgId, Map<String, String> spaceTempMap,
                           Map<String, PtUserRole> areadySpaceIdMap) {
        EntityWrapper<PtUserRole> model = new EntityWrapper<>();
        model.eq("account_id",id);
        model.eq("org_id",orgId);
        List<PtUserRole> lst = userRoleService.selectList(model);
        String spkey = "";
        for (PtUserRole us : lst) { // 记录已有身份
            spkey = getUserKey(id, us);
            spaceTempMap.put(spkey, "");
            areadySpaceIdMap.put(spkey, us);
        }

    }
    // 拼接用户身份key
    private String getUserKey(String id, PtUserRole userRole) {
        return new StringBuilder().append(id).append("_l")
                .append(nullToempty(userRole.getRoleId())).append("_s")
                .append(nullToempty(userRole.getSubjectId())).append("_g")
                .append(nullToempty(userRole.getGradeId())).append("_p")
                .append(nullToempty(userRole.getPhaseId())).toString();
    }
    private String nullToempty(Object o) {
        if (o == null) {
            return "";
        }

        return o.toString();
    }
    private PtUserRole newUserRole(int i, String name, String orgId, String phase,
                                 String grade, String subject, PtRole role, Map<String, Object> params,
                                 StringBuilder returnMsg, Integer userType) {
        Integer phaseId = (Integer) params.get("phaseId");
        Integer subjectId = 0;
        Integer gradeId = 0;

        PtUserRole userSpace = new PtUserRole();
        @SuppressWarnings("unchecked")
        Map<String, Object> metaMap = (Map<String, Object>) params.get("metaMap");
        if (role != null) {
            if (phaseId == null && role.getShowPhase()) { // 需要有学段
                if (StringUtils.isBlank(phase)) {
                    returnMsg.append("数据错误：第" + (i) + "行中的‘学段’应为必填项,已自动忽略;<br>");
                    return null;
                } else if (metaMap.get(phase) == null) {
                    returnMsg.append("数据错误：第" + (i) + "行账号已经导入，‘学段’字段在该校不存在,已自动忽略;<br>");
                    return null;
                } else {
                    phaseId = (Integer) metaMap.get(phase);
                }
            }

            if (role.getShowSubject()) { // 设置学科
                if (StringUtils.isBlank(subject)) {
                    returnMsg.append("数据格式错误：第" + (i) + "行中的‘学科’应为必填,已自动忽略;<br>");
                    return null;
                }

                try {
                    subjectId = (Integer) metaMap.get(subject);
                } catch (NumberFormatException e) {
                    logger.warn("subject `{}` not exist in school", subject);
                }

                if (subjectId == null || subjectId == 0) {
                    returnMsg.append("数据格式错误：第" + (i) + "行账号已经导入，‘学科’在该校中不存在,已自动忽略;<br>");
                    return null;
                }
            }

            if (role.getShowGrade()) { // 设置年级
                if (StringUtils.isBlank(grade)) {
                    returnMsg.append("数据格式错误：第" + (i) + "行中的‘年级’应为必填,已自动忽略;<br>");
                    return null;
                }

                try {
                    gradeId = (Integer) (metaMap.get(grade));
                } catch (NumberFormatException e) {
                    logger.info("grade `{}` not exists in school", e);
                }

                if (gradeId == null || gradeId == 0) {
                    returnMsg.append("数据格式错误：第" + (i) + "行账号已经导入，‘年级’在该校中不存在,已自动忽略;<br>");
                    return null;
                }
            }
            userSpace.setRoleId(role.getId());
        }
        userSpace.setName(name);
        userSpace.setOrgId(orgId);
        userSpace.setPhaseId(phaseId);
        userSpace.setSubjectId(subjectId);
        userSpace.setGradeId(gradeId);
        userSpace.setSysRoleId(userType);
        userSpace.setEnable(true);
        return userSpace;
    }
    private CommUser fillCommUserInfo(Integer userType, Map<ExcelTitle, String> rowValueMap) {
        CommUser userInfo = createUser(userType);
        String birthdayStr = rowValueMap.get(ExcelHeader.BIRTHDAY);
        Date birthday = null;
        if (!StringUtils.isBlank(birthdayStr)) {
            try {
                birthday = DateUtils.parseDate(birthdayStr);
            } catch (Exception e) {
                // do nothing
            }
        }
        userInfo.setId(rowValueMap.get(ExcelHeader.ID));
        userInfo.setName(rowValueMap.get(ExcelHeader.NAME));
        userInfo.setSex(GBSex.forCode(rowValueMap.get(ExcelHeader.SEX)));
        userInfo.setPapersType(GBPapersType.forCode(rowValueMap.get(ExcelHeader.PAPERSTYPE)));
        userInfo.setPapersNumber(rowValueMap.get(ExcelHeader.PAPERSNUMBER));
        if (userInfo.getPapersType() == null) {
            String idcard = rowValueMap.get(ExcelHeader.IDCARD);
            if (idcard != null) {
                if (idcard.length() > 18) {
                    idcard = idcard.substring(0, 18);
                }
                userInfo.setPapersNumber(idcard);
                userInfo.setPapersType(GBPapersType.IDCARD.getCode());
            }
        }

        userInfo.setNationCode(GBNation.forCode(rowValueMap.get(ExcelHeader.NATION)));
        userInfo.setNativePlace(rowValueMap.get(ExcelHeader.NATIVEPLACE));
        userInfo.setFamilyAddress(rowValueMap.get(ExcelHeader.FAMILYADDRESS));
        userInfo.setBirthday(birthday);
        userInfo.setPostCode(rowValueMap.get(ExcelHeader.POSTCODE));
        userInfo.setTelephone(rowValueMap.get(ExcelHeader.TELEPHONE));
        userInfo.setCellphone(rowValueMap.get(ExcelHeader.PHONE));
        userInfo.setEmail(rowValueMap.get(ExcelHeader.EMAIL));
        userInfo.setEnable(true);
        userInfo.setCrtDttm(new Date());

        switch (userType) {
            case PtAccount.STUDENT_USER:
                Student student = (Student) userInfo;
                student.setGraduateState(5);
                student.setStudentCode(rowValueMap.get(ExcelHeader.STUDENTCODE));
                student.setParentsName(rowValueMap.get(ExcelHeader.PARENTSNAME));
                student.setParentsPhone(rowValueMap.get(ExcelHeader.PARENTSPHONE));
                student.setStudentCardId(rowValueMap.get(ExcelHeader.STUDENTCARDID));

                break;

            case PtAccount.AREA_USER:
                break;
            case PtAccount.TEACHER_USER:
                Teacher tea = (Teacher) userInfo;
                tea.setSchoolCard(rowValueMap.get(ExcelHeader.STUDENTCARDID));
                break;
            default:
                People peope = (People) userInfo;
                peope.setUserType(userType);
                break;
        }

        return userInfo;
    }
    enum ExcelHeader implements ExcelTitle {
        ID(32, "账号"),
        ACCOUNT(64, "用户名"),
        NAME(true, 32, "姓名", "真实姓名"),
        SEX(20, "性别"),
        ROLETYPE(20, "角色类型", "角色"),
        ROLE(20, "职务"),
        DEPARTMENT(50, "部门", "所属部门"),
        SUBJECT(20, "学科"),
        GRADE(20, "年级"),
        PHASE(20, "学段"),
        PAPERSTYPE(20, "证件类型"),
        PAPERSNUMBER(32, "证件号"),
        IDCARD(32, "身份证号"),
        BIRTHPLACE(200, "出生地"),
        NATION(20, "民族"),
        POLITICAL(50, "团员面貌"),
        BIRTHDAY(20, "出生日期"),
        STUDENTCODE(32, "学籍号"),
        STUDENTCARDID(20, "校卡号"),
        SCHOOLCARD(20, "校卡号"),
        PARENTSNAME(20, "家长姓名"),
        PARENTSPHONE(20, "家长联系方式", "家长手机号"),
        NATIVEPLACE(200, "籍贯"),
        PID(32, "父级机构"),
        ADDRESS(200, "地址"),
        NOTE(1000, "简介"),
        SITEID(32, "分站点"),
        ORGCODE(32, "机构号"),
        POSTCODE(20, "邮编"),
        WEBSITE(512, "学校网址"),
        LEADER(32, "联系人"),
        FAMILYADDRESS(200, "家庭地址"),
        TELEPHONE(20, "联系方式", "固定电话"),
        PHONE(20, "手机", "手机号"),
        LEADERPHONE(20, "负责人电话"),
        EMAIL(100, "电子邮件", "电子邮箱", "电子信箱");

        private String[] mapNames;

        private boolean required = false;

        private Integer size = null;

        private ExcelHeader(String... header) {
            this.mapNames = header;
        }

        private ExcelHeader(boolean required, String... header) {
            this.mapNames = header;
            this.required = required;
        }

        private ExcelHeader(Integer size, String... header) {
            this.mapNames = header;
            this.size = size;
        }

        private ExcelHeader(boolean required, Integer size, String... header) {
            this.mapNames = header;
            this.required = required;
            this.size = size;
        }

        @Override
        public List<String> getMapNames() {
            return Arrays.asList(mapNames);
        }

        @Override
        public boolean isRequired() {
            return required;
        }

        /**
         * @return 返回
         */
        @Override
        public int length() {
            return size;
        }
    }
    /**
     * 获取机构用户元数据的Id——名称map
     *
     * @param orgId   机构id
     * @param phaseId 学段id
     * @return 返回
     */
    private Map<String, Object> getMetaMap(Integer phaseId, String orgId) {
        PtOrg o = orgService.selectById(orgId);
        Map<String, Object> metaMap = new HashMap<String, Object>();
        if (o != null) {
            List<Meta> subjects = new ArrayList<>();
            List<Meta> grades = new ArrayList<>();
            Integer[] areaIds = this.getAreaIds(o);
            if (PtOrg.TP_SCHOOL == o.getType()) {

                subjects = MetaUtils.getPhaseSubjectProvider().listAllSubject(orgId, phaseId, areaIds);
                grades = MetaUtils.getOrgTypeProvider().listAllGrade(o.getSchoolings(), phaseId);
            } else if (PtOrg.TP_ORG == o.getType()) {
                // 加入学段元数据
                List<Meta> setionMeataList = MetaUtils.getPhaseProvider().listAll();
                for (Meta setion : setionMeataList) {
                    metaMap.put(setion.getName(), setion.getId());
                }

                subjects = MetaUtils.getPhaseSubjectProvider().listAllSubject(null, phaseId, areaIds);// 区域所有学科，应该通过areaids
            }

            for (Meta m : subjects) {
                metaMap.put(m.getName(), m.getId());
            }
            for (Meta m : grades) {
                metaMap.put(m.getName(), m.getId());
            }

            // 加入部门
            EntityWrapper<PtOrg> orgTemp = new EntityWrapper<>();
            orgTemp.eq("id",orgId);
            orgTemp.eq("type",PtOrg.TP_DEP);
            List<PtOrg> bumenList = orgService.selectList(orgTemp);

            for (PtOrg org : bumenList) {
                metaMap.put(org.getName(), org.getId());
            }
        }
        return metaMap;
    }
    // 初始化角色类型
    private Map<String, PtRole> initRole(String orgId, Integer scope) {
        Map<String, PtRole> roleMap = new HashMap<String, PtRole>();
        // 加入角色元数据
        List<PtRole> roleList = roleService.getRoleByScope(orgId, scope);// roleService.findRoleListByUseOrgId(orgId,scope);
        for (PtRole role : roleList) {
            roleMap.put(role.getRoleName(), role);
        }
        return roleMap;
    }
    @Override
    protected void beforeSheetParse(Sheet sheet, Map<String, Object> params, StringBuilder returnMsg) {
        params.put("batchSpaceList", new ArrayList<PtUserRole>());
        params.put("spaceTempMap", new HashMap<String, String>());
        params.put("areadySpaceIdMap", new HashMap<String, PtUserRole>());// 已经存在的用户空间id
        params.put("userTempMap", new HashMap<String, CommUser>()); // 临时用户map<用户姓名，用户object>,用于判断待插入的数据是否重复
        params.put("userRoleTypeMap", new HashMap<String, SysRole>());// 用户角色类型集合

        params.put("batchDeleteUserList", new ArrayList<CommUser>());// 待删除用户集合
        params.put("beforeInsertTime", new Date());// 开始插入时间

        String orgId = (String) params.get(ORG_ID);
        Integer phaseId = (Integer) params.get("phaseId");
        params.put("metaMap", getMetaMap(phaseId, orgId));

        Integer userType = (Integer) params.get(USERTYPE);
        if (PtAccount.AREA_USER == userType) {
            params.put("roleMap", initRole(orgId, PtRoleType.APPLICATION_AREA));
        } else {
            params.put("roleMap", initRole(orgId, PtRoleType.APPLICATION_SCHOOL));
        }
    }


    @Override
    protected void endSheetParse(Sheet sheet, Map<String, Object> params, StringBuilder returnMsg) {
        if (params != null) {
            Integer userType = (Integer) params.get(USERTYPE);
            Map<String, PtUserRole> areadySpaceIdMap = (Map<String, PtUserRole>) params.get("areadySpaceIdMap");// 需要删除的用户空间id
            List<CommUser> batchDeleteUserList = (ArrayList<CommUser>) params.get("batchDeleteUserList");// 待删除用户集合
            Set<CommUser> batchUpdateUserList = (HashSet<CommUser>) params.get("batchUpdateUserList");// 待更新用户角色集合
            Set<String> deleteSpaceIdSet = new TreeSet<String>();// 需要删除的用户空间id

            for (PtUserRole space : areadySpaceIdMap.values()) { // 删除用户空间，不发消息
                if (space != null && space.getId() != null && !deleteSpaceIdSet.contains(space.getId())) {
                    deleteSpaceIdSet.add(space.getId());
                    userRoleService.deleteById(space.getId());
                    CommUser cu = createUser(userType);
                    cu.setId(space.getAccountId());
                    batchUpdateUserList.add(cu);
                }
            }

            for (CommUser user : batchDeleteUserList) { // 删除垃圾用户数据，不发消息
                if (user != null && user.getId() != null) {
                    if (user instanceof EduEmployee) {
                        eduEmpService.deleteById(user.getId());
                    } else if (user instanceof Teacher) {
                        teacherService.deleteById(user.getId());
                    } else if (user instanceof Student) {
                        studentService.deleteById(user.getId());
                    } else if (user instanceof People) {
                        peopleService.deleteById(user.getId());
                    }
                }
            }

            List<CommUser> userInfos = (List<CommUser>) params.get("batchUserList");
            if (userInfos.size()>0) {
                batchSave(userType, userInfos);
            }
            // 开始批量插入
            List<PtUserRole> batchSpaceList = (List<PtUserRole>) params.get("batchSpaceList"); // 待插入用户空间集合
            if (batchSpaceList.size()>0) {
                userRoleService.insertBatch(batchSpaceList);
            }

            Date now = new Date();
            for (CommUser teacher : batchUpdateUserList) {
                if (teacher != null && teacher.getId() != null) {
                    teacher.setLastupDttm(now);
                    if (teacher instanceof EduEmployee) {
                        eduEmpService.updateAllColumnById((EduEmployee) teacher);
                    } else if (teacher instanceof Teacher) {
                        teacherService.updateAllColumnById((Teacher) teacher);
                    } else if (teacher instanceof Student) {
                        studentService.updateAllColumnById((Student) teacher);
                    } else if (teacher instanceof People) {
                        peopleService.updateAllColumnById((People) teacher);
                    }
                }
            }

        }

    }
    private void batchSave(Integer userType, List<CommUser> userInfos) {
        if (PtAccount.AREA_USER == userType) {
            List<EduEmployee> batchUserList = this.<EduEmployee>changeUserType(userInfos);
            //fireListenableEvent(EVENT_BEFORE_SAVE_USER, batchUserList);
            eduEmpService.insertBatch(batchUserList);
        } else if (PtAccount.TEACHER_USER == userType) {
            List<Teacher> batchUserList = this.<Teacher>changeUserType(userInfos);
            //fireListenableEvent(EVENT_BEFORE_SAVE_USER, batchUserList);
            teacherService.insertBatch(batchUserList);
        } else if (PtAccount.STUDENT_USER == userType) {
            List<Student> batchUserList = this.<Student>changeUserType(userInfos);
            //fireListenableEvent(EVENT_BEFORE_SAVE_USER, batchUserList);
            studentService.insertBatch(batchUserList);
        } else if (PtAccount.PARENTS_USER == userType) {
            List<People> batchUserList = this.<People>changeUserType(userInfos);
            //fireListenableEvent(EVENT_BEFORE_SAVE_USER, batchUserList);
            peopleService.insertBatch(batchUserList);
        }

    }
    private <T> List<T> changeUserType(List<CommUser> userInfos) {
        List<T> batchUserList = new ArrayList<T>();
        for (CommUser u : userInfos) {
            batchUserList.add((T) u);
        }
        return batchUserList;
    }

    private CommUser createUser(Integer userType) {
        CommUser user;
        switch (userType) {
            case PtAccount.AREA_USER:
                user = new EduEmployee();
                break;
            case PtAccount.TEACHER_USER:
                user = new Teacher();
                break;
            case PtAccount.STUDENT_USER:
                user = new Student();
                break;
            default:
                user = new People();
        }

        return user;

    }

    @Override
    protected boolean isRequiredColumn(String columnName) {
        if (columnName != null) {
            return columnName.contains("必填");
        }
        return super.isRequiredColumn(columnName);
    }
}
